home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 078 (1990-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 078 (1990-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / MSH / src / date.c next >
C/C++ Source or Header  |  1990-06-17  |  4KB  |  165 lines

  1. /*-
  2.  * $Id: date.c,v 1.30 90/06/04 23:18:11 Rhialto Rel $
  3.  * $Log:    date.c,v $
  4.  * Revision 1.30  90/06/04  23:18:11  Rhialto
  5.  * Release 1 Patch 3
  6.  * 
  7.  * DATE.C
  8.  *
  9.  * Two date conversion routines: DateStamp <-> MSDOS date/time.
  10.  *
  11.  * This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
  12.  * not be used or copied without a licence.
  13.  */
  14.  
  15. #include <libraries/dos.h>
  16. #include "han.h"
  17.  
  18. #define BASEYEAR        1978
  19. #define DAYS_PER_YEAR        365
  20. #define HOURS_PER_DAY        24
  21. #define MINUTES_PER_HOUR    60
  22. #define SECONDS_PER_MINUTE  60
  23.  
  24. #define DAYS_PER_WEEK        7
  25. #define MONTHS_PER_YEAR     12
  26.  
  27. #define MINUTES_PER_DAY     (MINUTES_PER_HOUR * HOURS_PER_DAY)
  28. #define SECONDS_PER_DAY     ((long) SECONDS_PER_MINUTE * \
  29.                  MINUTES_PER_HOUR * HOURS_PER_DAY)
  30.  
  31. #define LeapYear(year)  ((year & 3) == 0)   /* From 1-Mar-1901 to 28-Feb-2100 */
  32.  
  33. int daycount[MONTHS_PER_YEAR] = {
  34.     31,    28,    31,    30,    31,    30,
  35.     31,    31,    30,    31,    30,    31
  36. };
  37.  
  38. void
  39. ToDateStamp(datestamp, date, time)
  40. struct DateStamp *datestamp;
  41. word date;
  42. word time;
  43. {
  44.     {
  45.     int hours, minutes, seconds;
  46.  
  47.     seconds = (time & 31) * 2;
  48.     time >>= 5;
  49.     minutes = time & 63;
  50.     time >>= 6;
  51.     hours = time;
  52.  
  53.     datestamp->ds_Minute = MINUTES_PER_HOUR * hours + minutes;
  54.     datestamp->ds_Tick = TICKS_PER_SECOND * seconds;
  55.     }
  56.  
  57.     {
  58.     ulong i, j, t;
  59.     int year, month, day;
  60.  
  61.     if (date < DATE_MIN)
  62.         date = DATE_MIN;
  63.  
  64.     day = date & 31;
  65.     date >>= 5;
  66.     month = (date & 15) - 1;
  67.     date >>= 4;
  68.     year = date + 1980;
  69.  
  70.     if ((unsigned)month > 11 ||
  71.         (unsigned)day > (unsigned)daycount[month]) {
  72.         day = 31;
  73.         month = 11;
  74.         year = 1979;
  75.     }
  76.  
  77.     j = year - BASEYEAR;
  78.  
  79.     /* Get the next lower full leap period (4 years and a day) since ... */
  80.     t = (year - BASEYEAR) & ~3;
  81.     i = t;
  82.     t = (t / 4) * (4 * DAYS_PER_YEAR + 1);
  83.  
  84.     /* t now is the number of days in 4 whole years since ... */
  85.  
  86.     /*dbprintf(("ly0: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
  87.     while (i < j) {
  88.         /*dbprintf(("ly1: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
  89.         t += DAYS_PER_YEAR;
  90.         if (LeapYear(i + BASEYEAR)) {
  91.         /*dbprintf(("leap year\n"));*/
  92.         t++;
  93.         }
  94.         i++;
  95.     }
  96.  
  97.     /* t now is the number of days in whole years since ... */
  98.  
  99.     /*dbprintf(("m0:  i=%ld j=%ld t=%ld\n", i, j, t));*/
  100.     for (i = 0; i < month; i++) {
  101.         /*dbprintf(("m1: i=%ld j=%ld t=%ld\n", i, j, t));*/
  102.         t += daycount[i];
  103.         if (i == 1 && LeapYear(year)) {
  104.         t++;
  105.         }
  106.     }
  107.  
  108.     /* t now is the number of days in whole months since ... */
  109.  
  110.     t += day - 1;
  111.  
  112.     /* t now is the number of days in whole days since ... */
  113.  
  114.     datestamp->ds_Days = t;
  115.     }
  116. }
  117.  
  118. void
  119. ToMSDate(date, time, datestamp)
  120. word *date;
  121. word *time;
  122. register struct DateStamp *datestamp;
  123. {
  124.     {
  125.     word hours, minutes, seconds;
  126.  
  127.     hours = datestamp->ds_Minute / MINUTES_PER_HOUR;
  128.     minutes = datestamp->ds_Minute % MINUTES_PER_HOUR;
  129.     seconds = datestamp->ds_Tick / TICKS_PER_SECOND;
  130.  
  131.     *time = (hours << 11) | (minutes << 5) | (seconds / 2);
  132.     }
  133.     {
  134.     register long days, i, t;
  135.     int year, month, day;
  136.  
  137.     days = datestamp->ds_Days;
  138.  
  139.     year = BASEYEAR + (days/(4*DAYS_PER_YEAR+1)) * 4;
  140.     days %= 4 * DAYS_PER_YEAR + 1;
  141.     while (days) {
  142.         t = DAYS_PER_YEAR;
  143.         if (LeapYear(year))
  144.             t++;
  145.         if (days < t)
  146.             break;
  147.         days -= t;
  148.         year++;
  149.     }
  150.     days++;
  151.     for (i = 0; i < MONTHS_PER_YEAR; i++) {
  152.         t = daycount[i];
  153.         if (i == 1 && LeapYear(year))
  154.             t++;
  155.         if (days <= t)
  156.             break;
  157.         days -= t;
  158.     }
  159.     month = i + 1;
  160.     day = days;
  161.  
  162.     *date = ((year - 1980) << 9) | (month << 5) | day;
  163.     }
  164. }
  165.